﻿using System;
using System.Collections.Generic;
using System.Linq;
using EnvDTE;
using Microsoft.VisualStudio.TemplateWizard;
using System.Windows.Forms;

namespace AutoWrockTestable.Template
{
    public class TestableWizard : IWizard
    {
        private bool shouldAddProjectItem = true;

        public void RunStarted(object automationObject, Dictionary<string, string> replacementsDictionary, WizardRunKind runKind, object[] customParams)
        {
            var dte = automationObject as DTE;
            var types = new TypeLoaderService(dte).LoadTypes();
            string currentClass = null;
            if (dte.ActiveDocument != null && dte.ActiveDocument.ProjectItem != null && dte.ActiveDocument.ProjectItem.FileCodeModel != null)
            {
                var codeModel = dte.ActiveDocument.ProjectItem.FileCodeModel;
                for (var ii = 1; ii <= codeModel.CodeElements.Count; ii++)
                {
                    var element = codeModel.CodeElements.Item(ii);
                    currentClass = ExtractTypeFromCodeElement(element);
                    if(currentClass != null)
                        break;
                }
            }

            try
            {
                var inputForm = new TestableForm(types.Select(x => x.FullName), currentClass);
                inputForm.ShowDialog();

                var className = inputForm.ClassName ?? string.Empty;
                className = className.Trim();
                while (className.EndsWith("."))
                    className = className.Substring(0, className.Length - 1);
                var element = types.FirstOrDefault(x => x.FullName.Equals(className, StringComparison.InvariantCultureIgnoreCase));
                ClassName testClass = element != null ? new ClassName(element.FullName, element.Name) : new ClassName(className, className);

                if (!string.IsNullOrEmpty(testClass.ShortName))
                {
                    replacementsDictionary["$classNameToTest$"] = testClass.ShortName;
                    replacementsDictionary["$classToTest$"] = testClass.FullName;
                }
                else
                    shouldAddProjectItem = false;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        private string ExtractTypeFromCodeElement(CodeElement element)
        {
            if (element.Kind == vsCMElement.vsCMElementStruct || element.Kind == vsCMElement.vsCMElementClass)
                return element.FullName;
            if (element.Children.Count > 0)
            {
                for (var i = 1; i <= element.Children.Count; i++)
                {
                    var child = element.Children.Item(i);
                    var name = ExtractTypeFromCodeElement(child);
                    if (name != null)
                        return name;
                }
            }

            return null;
        }

        public void ProjectFinishedGenerating(Project project)
        {
        }

        public void ProjectItemFinishedGenerating(ProjectItem projectItem)
        {
        }

        public bool ShouldAddProjectItem(string filePath)
        {
            return shouldAddProjectItem;
        }

        public void BeforeOpeningFile(ProjectItem projectItem)
        {
        }

        public void RunFinished()
        {
        }
    }
}
